package com.ymt.bpm.web.action.platform;

import com.ymt.bpm.util.AES;
import com.ymt.bpm.util.Const;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.savedrequest.DefaultSavedRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.Map;

/**
 * Created by Johnny on 2017/2/2.
 */
@Controller
public class IndexController {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private Environment env;

    @RequestMapping(path="/")
    public ModelAndView index(HttpServletRequest request) {
        try {
            request.getSession();   //avoid IllegalStateException
        } catch (Exception e) {
            return null;
        }
        Map<String, String> userDetail = (Map<String, String>)SecurityContextHolder.getContext().getAuthentication().getDetails();
        String tenantId = userDetail.get(Const.TENANT_ID);
        String lang = userDetail.get(Const.LANG);
        String displayName = userDetail.get(Const.DISPLAYNAME);
        String[] profile = env.getActiveProfiles();
        String productionVersion = env.getProperty("bpmp.production-version", "0");
        String cdn = env.getProperty("bpmp.cdn", "/bpmp-resources");
        String prefixHandleTask = env.getProperty("bpmp.prefix.handletask");
        String prefixViewpi = env.getProperty("bpmp.prefix.viewpi");
        String prefixStartpi = env.getProperty("bpmp.prefix.startpi");
        ModelAndView view = new ModelAndView("index");
        view.addObject("profile", profile[0]);
        view.addObject("productionVersion", productionVersion);
        view.addObject("cdn", cdn);
        view.addObject(Const.LANG, lang);
        view.addObject(Const.DISPLAYNAME, displayName);
        view.addObject(Const.TENANT_ID, AES.encrypt(tenantId==null ? "0" : tenantId));
        view.addObject("prefixHandleTask", prefixHandleTask);
        view.addObject("prefixViewpi", prefixViewpi);
        view.addObject("prefixStartpi", prefixStartpi);
        return view;
    }

    @RequestMapping(path="/login")
    public ModelAndView login(HttpServletRequest request) {
        String[] profile = env.getActiveProfiles();
        String productionVersion = env.getProperty("bpmp.production-version", "0");
        String cdn = env.getProperty("bpmp.cdn", "/bpmp-resources");
        boolean fail = request.getParameterMap().containsKey("fail");
        //get redirect url
        String succssUrl = "/";
        DefaultSavedRequest dsr = (DefaultSavedRequest)request.getSession().getAttribute("SPRING_SECURITY_SAVED_REQUEST");
        if (dsr!=null) {
            succssUrl = dsr.getRequestURI();
            if (log.isTraceEnabled()) {
                log.trace("getRequestURI="+dsr.getRequestURI());
                log.trace("getRequestURL="+dsr.getRequestURL());
                log.trace("getRedirectUrl="+dsr.getRedirectUrl());
                log.trace("succssUrl="+succssUrl);
            }
        }

        ModelAndView view = new ModelAndView("login");
        view.addObject("profile", profile[0]);
        view.addObject("productionVersion", productionVersion);
        view.addObject("cdn", cdn);
        view.addObject("authtype", env.getProperty("bpmp.auth-type"));
        view.addObject("fail", fail ? "fail" : "");
        view.addObject("successUrl", succssUrl);

        return view;
    }

    @RequestMapping(path="/topage")
    public ModelAndView topage(HttpServletRequest request) {
        Map<String, String> userDetail = (Map<String, String>)SecurityContextHolder.getContext().getAuthentication().getDetails();
        String path = request.getParameter("path");
        String lang = userDetail.get(Const.LANG);
        ModelAndView view = new ModelAndView(path);
        String[] profile = env.getActiveProfiles();
        String productionVersion = env.getProperty("bpmp.production-version", "0");
        String cdn = env.getProperty("bpmp.cdn", "/bpmp-resources");
        view.addObject("profile", profile[0]);
        view.addObject("productionVersion", productionVersion);
        view.addObject("cdn", cdn);
        view.addObject(Const.LANG, lang);

        //redirect other parameters
        Enumeration<String> paramEnu = request.getParameterNames();
        while(paramEnu.hasMoreElements()) {
            String param = paramEnu.nextElement();
            view.addObject(param, request.getParameter(param));
        }

        return view;
    }

    @GetMapping(path="/logout")
    public ModelAndView logout(HttpServletRequest req, HttpServletResponse resp) {
        String path = req.getParameter("path");
        if (path==null) {
            path = req.getContextPath();
            if (path!=null && path.length()==0) {
                path = "/";
            }
        }

        if (log.isDebugEnabled()) {
            log.debug("path="+path);
        }

        //remove session
        Enumeration<String> attrs = req.getSession().getAttributeNames();
        while (attrs.hasMoreElements()) {
            req.getSession().removeAttribute(attrs.nextElement());
        }
        req.getSession().invalidate();

        //remove all cookies
        Cookie[] cookies = req.getCookies();
        for (Cookie cookie:cookies) {
            cookie.setPath("/");
            cookie.setMaxAge(0);
            cookie.setValue(null);
            if (log.isDebugEnabled()) {
                log.debug("cookie ====== name: " + cookie.getName());
                log.debug("              value: "+cookie.getValue());
                log.debug("              path: " + cookie.getPath());
                log.debug("              domain: " + cookie.getDomain());
            }
        }

        //overwrite cookie
        Cookie cookie = new Cookie(Const.JWT_TOKEN, null);
        resp.addCookie(cookie);

        //call logout
        try {
            req.logout();
            //redirect logout url
            //resp.sendRedirect(path);
            return new ModelAndView("redirect:"+path);
        } catch (ServletException e) {
            e.printStackTrace();
        }

        return new ModelAndView(path);
    }

}
